#!/usr/bin/env python3
import sys
import json
import os
import subprocess
import time

# 日志文件路径
LOG_FILE = os.path.expanduser("~/.chrome_window_topmost_log.txt")
# 状态文件路径
STATE_FILE = os.path.expanduser("~/.chrome_window_topmost_state")

# 增强的日志函数
def log(message):
    """记录日志到文件和控制台，确保日志格式一致"""
    timestamp = time.strftime('%Y-%m-%d %H:%M:%S')
    log_message = f"[{timestamp}] {message}"
    print(log_message)
    try:
        with open(LOG_FILE, 'a', encoding='utf-8') as f:
            f.write(log_message + '\n')
    except Exception as e:
        print(f"日志写入失败: {e}", file=sys.stderr)

# 发送响应给Chrome扩展
def send_response(response):
    """向Chrome扩展发送JSON格式的响应，添加详细的错误处理"""
    try:
        # 确保响应包含基本字段
        if "message" not in response and not response.get("ok", False):
            response["message"] = "操作未成功完成"
            
        # 将响应转换为JSON字符串
        response_json = json.dumps(response)
        # 将JSON字符串编码为字节
        response_bytes = response_json.encode('utf-8')
        # 发送4字节的长度前缀
        sys.stdout.buffer.write(len(response_bytes).to_bytes(4, byteorder='little'))
        # 发送实际数据
        sys.stdout.buffer.write(response_bytes)
        # 确保数据被立即发送
        sys.stdout.buffer.flush()
        log(f"已发送响应: {response_json}")
    except Exception as e:
        log(f"发送响应失败: {e}")
        # 尝试发送简单的错误响应
        try:
            error_response = {"ok": False, "status": "INTERNAL_ERROR", "message": str(e)}
            error_json = json.dumps(error_response).encode('utf-8')
            sys.stdout.buffer.write(len(error_json).to_bytes(4, byteorder='little'))
            sys.stdout.buffer.write(error_json)
            sys.stdout.buffer.flush()
        except:
            pass  # 如果连错误响应都发不出去，就放弃

# 检查是否有权限执行AppleScript
def check_permissions(log_message):
    """检查脚本是否有权限控制系统事件"""
    try:
        # 简单测试脚本
        test_script = 'tell application "System Events" to return name of first process'
        result = subprocess.run(['osascript', '-e', test_script], 
                               capture_output=True, text=True, timeout=1)
        permission_status = result.returncode == 0
        log_message(f"权限检查结果: {'通过' if permission_status else '失败'}")
        return permission_status
    except Exception as e:
        log_message(f"权限检查失败: {e}")
        return False

# 检查是否是Chrome浏览器窗口
def is_chrome_browser():
    """检查调用此脚本的是否为Chrome浏览器"""
    try:
        # 获取父进程信息
        parent_info = subprocess.run(['ps', '-o', 'comm=', '-p', str(os.getppid())], 
                                   capture_output=True, text=True, timeout=1)
        parent_name = parent_info.stdout.strip()
        log(f"父进程名称: {parent_name}")
        return "Google Chrome" in parent_name or "chrome" in parent_name
    except Exception as e:
        log(f"获取父进程信息失败: {e}")
        # 如果无法确定，假设是Chrome
        return True

# 检查Chrome是否正在运行
def check_chrome_running(log_message):
    """检查Chrome是否正在运行"""
    script = '''
    tell application "System Events"
        set chrome_running to false
        repeat with proc in processes
            if name of proc is "Google Chrome" then
                set chrome_running to true
                exit repeat
            end if
        end repeat
        return chrome_running
    end tell
    '''
    try:
        result = subprocess.run(['osascript', '-e', script], capture_output=True, text=True, timeout=1)
        log_message(f"检查Chrome运行状态: {result.stdout.strip()}")
        return result.stdout.strip() == "true"
    except Exception as e:
        log_message(f"检查Chrome运行状态失败: {str(e)}")
        return False

# 获取Chrome窗口数量
def get_chrome_windows(log_message):
    """获取Chrome窗口数量"""
    script = '''
    tell application "Google Chrome"
        return count of windows
    end tell
    '''
    try:
        result = subprocess.run(['osascript', '-e', script], capture_output=True, text=True, timeout=1)
        window_count = int(result.stdout.strip()) if result.stdout.strip().isdigit() else 0
        log_message(f"Chrome窗口数量: {window_count}")
        return window_count
    except Exception as e:
        log_message(f"获取Chrome窗口数量失败: {str(e)}")
        return 0

# 增强的窗口激活方法 - 增加更多策略
def execute_enhanced_activation(log_message):
    """使用增强的AppleScript命令来确保Chrome窗口被正确激活"""
    log_message("开始执行增强的窗口激活策略")
    
    # 1. 检查Chrome是否正在运行
    if not check_chrome_running(log_message):
        log_message("Chrome未运行，无法执行置顶操作")
        return False
    
    # 2. 确保Chrome有窗口
    window_count = get_chrome_windows(log_message)
    if window_count == 0:
        log_message("Chrome没有打开的窗口")
        return False
    
    # 3. 使用简化的强制前置脚本，避免兼容性问题
    force_front_script = '''
    -- 第一步：简单激活Chrome
    tell application "Google Chrome"
        activate
        delay 0.3
    end tell
    
    -- 第二步：使用System Events强制设置frontmost
    tell application "System Events"
        tell process "Google Chrome"
            -- 简化的frontmost设置
            repeat 4 times
                set frontmost to true
                delay 0.1
            end repeat
            
            -- 简化的窗口操作
            try
                if exists window 1 then
                    perform action "AXRaise" of window 1
                end if
            end try
        end tell
    end tell
    
    -- 第三步：最后确认激活
    tell application "Google Chrome"
        activate
        delay 0.2
    end tell
    '''
    
    try:
        log_message("执行强制前置脚本")
        subprocess.run(['osascript', '-e', force_front_script], check=True, timeout=5)
    except Exception as e:
        log_message(f"执行强制前置脚本失败: {str(e)}")
    
    # 4. 确认是否成功
    confirm_script = '''
    tell application "System Events"
        tell process "Google Chrome"
            return frontmost
        end tell
    end tell
    '''
    
    time.sleep(0.5)  # 增加等待时间
    try:
        result = subprocess.run(['osascript', '-e', confirm_script], capture_output=True, text=True, timeout=1)
        success = result.stdout.strip() == "true"
        log_message(f"前置确认结果: {'成功' if success else '失败'}")
        
        # 5. 如果第一次失败，尝试更激进的替代方法
        if not success:
            log_message("首次尝试失败，使用替代方法")
            
            # 使用更强烈的键盘快捷键方法
            shortcut_script = '''
            -- 简化的替代方法
            tell application "Google Chrome"
                activate
                delay 0.2
            end tell
            
            tell application "System Events"
                -- 简单的Command+Tab切换
                key code 48 using {command down}
                delay 0.1
                key code 53 -- Escape键
                delay 0.2
                
                -- 确保frontmost设置
                tell process "Google Chrome"
                    set frontmost to true
                end tell
            end tell
            
            -- 最后激活
            tell application "Google Chrome"
                activate
                delay 0.2
            end tell
            '''
            
            try:
                subprocess.run(['osascript', '-e', shortcut_script], check=True, timeout=3)
                
                # 再次确认
                time.sleep(0.5)
                result = subprocess.run(['osascript', '-e', confirm_script], capture_output=True, text=True, timeout=1)
                success = result.stdout.strip() == "true"
                log_message(f"替代方法结果: {'成功' if success else '失败'}")
            except Exception as e:
                log_message(f"执行替代方法失败: {str(e)}")
        
        return success
    except Exception as e:
        log_message(f"确认前置状态失败: {str(e)}")
        return False

# 处理设置命令
def handle_setup(message, log_message):
    extension_id = message.get('extension_id', '')
    if not extension_id:
        log_message("未提供extension_id")
        send_response({"ok": False, "status": "UNKNOWN", "message": "缺少必要的extension_id参数"})
        return
    
    # 创建manifest文件
    home_dir = os.path.expanduser("~")
    manifest_dir = os.path.join(home_dir, "Library/Application Support/Google/Chrome/NativeMessagingHosts")
    os.makedirs(manifest_dir, exist_ok=True)
    
    manifest_path = os.path.join(manifest_dir, "com.topmost.chrome_window.json")
    origin = f"chrome-extension://{extension_id}/"
    
    # 获取当前脚本路径
    current_dir = os.path.dirname(os.path.abspath(__file__))
    executable_path = os.path.join(current_dir, "TopMostHost")
    
    # 确保脚本有执行权限
    try:
        os.chmod(executable_path, 0o755)
        log_message(f"已设置执行权限: {executable_path}")
    except Exception as e:
        log_message(f"设置执行权限失败: {e}")
    
    # 创建manifest内容，包含多个常见的扩展ID
    manifest = {
        "name": "com.topmost.chrome_window",
        "description": "Chrome窗口置顶原生主机",
        "path": executable_path,
        "type": "stdio",
        "allowed_origins": [
            origin,
            "chrome-extension://fbjlpkbeicpaekkomcahgnhbhoeghijb/",  # 已知的扩展ID
            "chrome-extension://bbfbkgcjpmjicohkmijggkfghgfijafd/"   # 另一个可能的扩展ID
        ]
    }
    
    try:
        with open(manifest_path, 'w') as f:
            json.dump(manifest, f, indent=2)
        
        log_message(f"Manifest已创建: {manifest_path}")
        send_response({"ok": True, "status": "SETUP_DONE", "manifestPath": manifest_path, "origin": origin})
    except Exception as e:
        log_message(f"创建Manifest失败: {str(e)}")
        send_response({"ok": False, "status": "SETUP_ERROR", "message": f"创建配置文件失败: {str(e)}"})

# 处理窗口控制命令
def handle_window_command(command, log_message):
    try:
        # 检查权限
        if not check_permissions(log_message):
            log_message("没有足够权限控制系统事件")
            return {"ok": False, "status": "PERMISSION_DENIED", "message": "需要授予终端控制您的计算机的权限"}
        
        # 检查是否是Chrome浏览器调用
        if not is_chrome_browser():
            log_message("警告: 非Chrome浏览器调用")
            # 仍然处理命令，但记录警告
        
        if command == "query":
            # 检查状态文件是否存在
            is_topmost = os.path.exists(STATE_FILE)
            status = "TOPMOST" if is_topmost else "NOTOPMOST"
            log_message(f"查询状态: {status}")
            message = "Chrome窗口当前处于置顶状态" if is_topmost else "Chrome窗口当前未置顶"
            return {"ok": True, "status": status, "message": message}
            
        elif command == "set":
            # 先执行增强的窗口激活，成功后再创建状态文件
            activation_success = execute_enhanced_activation(log_message)
            
            if activation_success:
                # 创建状态文件
                with open(STATE_FILE, 'w') as f:
                    f.write("TOPMOST")
                log_message("设置置顶状态成功")
                return {"ok": True, "status": "TOPMOST", "message": "Chrome窗口已成功置顶"}
            else:
                log_message("窗口激活失败，无法设置置顶")
                return {"ok": False, "status": "ACTIVATION_FAILED", "message": "无法激活Chrome窗口，请检查权限设置"}
            
        elif command == "unset":
            # 删除状态文件
            if os.path.exists(STATE_FILE):
                os.remove(STATE_FILE)
                log_message("取消置顶状态")
            return {"ok": True, "status": "NOTOPMOST", "message": "已取消Chrome窗口置顶"}
            
        else:  # toggle
            # 切换状态
            if os.path.exists(STATE_FILE):
                os.remove(STATE_FILE)
                log_message("切换到非置顶状态")
                return {"ok": True, "status": "NOTOPMOST", "message": "已切换到非置顶状态"}
            else:
                # 先执行增强的窗口激活，成功后再创建状态文件
                activation_success = execute_enhanced_activation(log_message)
                
                if activation_success:
                    with open(STATE_FILE, 'w') as f:
                        f.write("TOPMOST")
                    log_message("切换到置顶状态成功")
                    return {"ok": True, "status": "TOPMOST", "message": "已切换到置顶状态"}
                else:
                    log_message("窗口激活失败，无法设置置顶")
                    return {"ok": False, "status": "ACTIVATION_FAILED", "message": "无法激活Chrome窗口，请检查权限设置"}
    
    except Exception as e:
        log_message(f"处理窗口命令失败: {str(e)}")
        return {"ok": False, "status": "ERROR", "message": f"处理命令时发生错误: {str(e)}"}

# 主函数
def main():
    """主函数，处理与Chrome扩展的通信"""
    # 清空日志文件
    try:
        with open(LOG_FILE, 'w') as f:
            f.write(f"[{time.strftime('%Y-%m-%d %H:%M:%S')}] === Chrome Window TopMost Host 已启动 ===\n")
    except Exception as e:
        print(f"清空日志文件失败: {e}", file=sys.stderr)
    
    log("=== Chrome Window TopMost Host 已启动 ===")
    
    while True:
        try:
            # 读取4字节的消息长度
            log("等待接收命令...")
            raw_length = sys.stdin.buffer.read(4)
            
            if not raw_length:
                log("未收到命令长度，退出")
                break
            
            # 解析消息长度
            length = int.from_bytes(raw_length, byteorder='little')
            log(f"接收到命令长度: {length}")
            
            # 读取实际的消息内容
            message = sys.stdin.buffer.read(length)
            
            if not message:
                log("未收到命令内容，退出")
                break
            
            # 解析JSON消息
            try:
                data = json.loads(message.decode('utf-8'))
                log(f"解析命令: {data}")
                
                # 获取命令
                command = data.get('command', 'toggle')
                
                # 处理不同类型的命令
                if command == 'setup':
                    handle_setup(data, log)
                else:
                    # 处理窗口命令并发送响应
                    response = handle_window_command(command, log)
                    send_response(response)
                    
            except json.JSONDecodeError as e:
                log(f"JSON解析失败: {e}")
                send_response({"ok": False, "status": "INVALID_JSON", "message": f"JSON格式错误: {str(e)}"})
            except Exception as e:
                log(f"处理命令异常: {e}")
                send_response({"ok": False, "status": "ERROR", "message": f"处理命令异常: {str(e)}"})
                
        except Exception as e:
            log(f"通信异常: {e}")
            break
    
    log("程序已退出")

if __name__ == "__main__":
    main()
